#include "serialport.h"
#include <QDebug>
#include "databasemanager.h"
#include <QSqlQuery>

SerialPort::SerialPort(QObject *parent) : QObject(parent)
{

    QList<QSerialPortInfo> list = QSerialPortInfo::availablePorts();
    for (int i = 0; i < list.size(); ++i)
    {
        // 目前只虚拟化了COM1和COM2，所以只会打印COM1和COM2
        qDebug() << "当前可用串口名称" << list.at(i).portName();
    }
}
// 设置串口的相关信息
void SerialPort::setSerialPort(QSerialPort *serial, const QString &portName)
{
    //1 选择要打开的端口
    serial->setPort(QSerialPortInfo(portName));
    //2设置波特率
    serial->setBaudRate(QSerialPort::Baud9600);
    //3设置奇偶校验位
    serial->setParity(QSerialPort::NoParity);
    //4设置停止位
    serial->setStopBits(QSerialPort::OneStop);
    //5打开串口
    bool info = serial->open(QIODevice::ReadWrite);
    if (info == true)
    {
        qDebug() << "打开串口成功" << portName;
    }
    else
    {
        qDebug() << "打开串口失败" << portName;
    }
}

void SerialPort::openAllCOM()
{
    DatabaseManager& dbManager = DatabaseManager::getInstance();

    if (!dbManager.connectMysql())
    {
        qDebug() << "COM打开数据库失败";
        return;
    }
    QSqlQuery query(dbManager.getDatabase());
    query.clear();
    query.prepare("SELECT com_nm FROM serialport_config");
    int i = 0;
    if (query.exec())
    {
        while (query.next())
        {
            i++;
            // 处理查询结果
            QString serialportName = query.value(0).toString();
            if (i % 2 != 0)
            {
                // 创建一个串口类对象
                QSerialPort* serial = new QSerialPort(this);
                this->setSerialPort(serial, serialportName);
                serialPorts.insert(serialportName, serial);
                connect(serial, &QSerialPort::readyRead, this, &SerialPort::readFromSerial);
            }
        }
    }
}

bool SerialPort::sendData(const QString &ComName, const QByteArray &data)
{
    if (!serialPorts.contains(ComName)) {
        qDebug() << "Error: Port" << ComName << "not found in configured ports.";
        return false;
    }

    QSerialPort *serial = serialPorts.value(ComName);
    if (!serial || !serial->isOpen()) {
        qDebug() << "Error: Port" << ComName << "is not open or does not exist.";
        return false;
    }

    qint64 bytesWritten = serial->write(data);
    if (bytesWritten == -1) {
        qDebug() << "Error writing to" << ComName << ":" << serial->errorString();
        return false;
    } else if (bytesWritten < data.size()) {
        qDebug() << "Warning: Not all data was written to" << ComName
                 << ". Wrote" << bytesWritten << "of" << data.size() << "bytes.";
        // 通常 QSerialPort::write 会阻塞直到所有数据写入或出错，
        // 但如果串口配置为非阻塞或者缓冲区问题，可能会出现部分写入。
        // serial->flush(); // 可以尝试刷新缓冲区，确保数据发出
        return true; // 即使部分写入，也认为操作尝试了
    } else {
        qDebug() << "Successfully wrote" << bytesWritten << "bytes to" << ComName << ":" << data.toHex(' ');
        // serial->flush(); // 有时需要确保数据立即发送，尤其是在快速关闭端口之前
        return true;
    }
}

void SerialPort::printSerialPorts()
{
    for (auto i = serialPorts.constBegin(); i != serialPorts.constEnd(); ++i)
    {
        qDebug() << i.key();
    }
}

void SerialPort::readFromSerial()
{
    QSerialPort *serial = qobject_cast<QSerialPort*>(sender());
    if (serial) {
        QByteArray data = serial->readAll();
        QString str = QString::fromLocal8Bit(data); // 保证发送的非ASCII码的中文能够打印出来
        qDebug() << "接收方串口" << serial->portName() << "接受的数据:" << str/*data*/;
        emit dataRecv(serial->portName(), data);
    }
}
